home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
Games
/
cbzone
/
c_explode.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-03
|
16KB
|
472 lines
#include "c_includes.h"
/*
* c_explode.c
* Todd W Mummert, CMU, January 1991
*
* This is an attempt at cleaning up the explosion routines. Why is this
* not the same as the drawing routines? probably should be, but because
* of the way pieces explode, the equations are more complex. Rather
* than slow down the draw routines, we just have a similiar, but
* different, set of equations here.
*/
/*
* the standard routine for exploding pieces, which will not take
* into account rotating objects.
*/
void calcpointsV(dc, method, index, g, pl)
DCp dc;
Methodp method;
int index;
Genericp g, pl;
{
int i;
float dx, dy, dz, xn, yn, zn, cn, sn, cp, sp, rx, ry, rz, prx, pry, prz;
Coord2dp new;
Coord3dp old;
old = dc->s->object+index;
new = dc->points+index;
dx = pl->x - g->x - dc->pos.x;
dy = pl->y - g->y - dc->pos.y;
dz = - dc->pos.z;
xn = dx*dc->cta + dy*dc->sta;
yn = -dx*dc->sta*dc->ctp + dy*dc->cta*dc->ctp + dz*dc->stp;
zn = dx*dc->sta*dc->stp - dy*dc->cta*dc->stp + dz*dc->ctp;
cn = pl->ca*dc->cta + pl->sa*dc->sta;
sn = pl->sa*dc->cta - pl->ca*dc->sta;
cp = dc->ctp;
sp = -dc->stp;
for (i=0; i<method->num; i++, old++, new++) {
rx = old->x - xn;
ry = old->y - yn;
rz = old->z - zn;
prx = rx*cn + ry*sn*cp + rz*sn*sp;
pry = -rx*sn + ry*cn*cp + rz*cn*sp;
if (pry < 10.0)
pry = 10.0;
prz = -ry*sp + rz*cp;
new->x = 500 + prx / pry * 450;
new->y = 260 - prz / pry * 450;
}
}
/*
* the routine that is used for drawing the exploding
* copter blade.
*/
void calcpointsVI(dc, method, index, g, pl)
DCp dc;
Methodp method;
int index;
Genericp g, pl;
{
int i;
float dx, dy, dz, xn, yn, zn, c1, s1, c2, s2, cp, sp;
float t1, t2, t3, t4, t5, t6, t7, t8, t9, rx, ry, rz, prx, pry, prz;
Coord2dp new;
Coord3dp old;
old = dc->s->object+index;
new = dc->points+index;
dx = pl->x - g->x - dc->pos.x;
dy = pl->y - g->y - dc->pos.y;
dz = - dc->pos.z;
xn = dx*dc->cta + dy*dc->sta*dc->ctp + dz*dc->sta*dc->stp;
yn = -dx*dc->sta + dy*dc->cta*dc->ctp + dz*dc->cta*dc->stp;
zn = -dy*dc->stp + dz*dc->ctp;
c1 = pl->ca*dc->cta;
s1 = pl->sa*dc->sta;
c2 = pl->ca*dc->sta;
s2 = pl->sa*dc->cta;
cp = dc->ctp;
sp = dc->stp;
t1 = c1 + s1 * cp;
t2 = -c2 + s2 * cp;
t3 = -pl->sa * sp;
t4 = -s2 + c2 * cp;
t5 = s1 + c1 * cp;
t6 = -pl->ca * sp;
t7 = dc->sta * sp;
t8 = dc->cta * sp;
t9 = cp;
for (i=0; i<method->num; i++, old++, new++) {
rx = old->x - xn;
ry = old->y - yn;
rz = old->z - zn;
prx = rx * t1 + ry * t2 + rz * t3;
pry = rx * t4 + ry * t5 + rz * t6;
prz = rx * t7 + ry * t8 + rz * t9;
if (pry < 10.0)
pry = 10.0;
new->x = 500 + prx / pry * 450;
new->y = 260 - prz / pry * 450;
}
}
void explodeobject(g, pl)
Genericp g, pl;
{
static float vars0[] = { 0.996195, 0.087156, 0.996195, 0.087156};
static float vars1[] = { 0.996195, -0.087156, 0.996195, -0.087156};
static float vars2[] = { 0.819152, 0.573576, 0.996195, 0.087156};
static Coord3d tank0[] = {
30, -53, -15, 35, -60, 15, 35, 60, -5, 30, 37, -15,
-30, 37, -15, -35, 60, -5, -35, -60, 15, -30, -53, -15,
30, -53, -15, 30, 37, -15, 35, -60, 15, -35, -60, 15,
35, 60, -5, -35, 60, -5, -30, -53, -15, -30, 37, -15};
static int tank0pnum[] = {10, 0};
static int tank0mnum[] = {6, 0};
static Method tank0methods[] = {16, calcpointsV, NULL,
0, NULL, NULL};
static Coord3d tank1[] = {
-10, -50, 10, -10, -18, 10, 10, -18, 10, 10, -50, 10,
25, -55, -11, 25, 55, -20, 10, -18, 10, -10, -18, 10,
-25, 55, -20, -25, -55, -11, -10, -50, 10, 10, -50, 10};
static int tank1pnum[] = {12, 0};
static int tank1mnum[] = {0};
static Method tank1methods[] = {12, calcpointsV, NULL,
0, NULL, NULL};
static Coord3d tank2[] = {
-3, 28, -3, 3, 28, -3, 3, 28, 3, -3, 28, 3,
-3, 28, -3, 3, -28, 3, 3, 28, 3, -3, -28, 3,
-3, 28, 3, -3, -13, -3, -3, 28, -3, 3, -13, -3,
3, 28, -3};
static int tank2pnum[] = {5, 0};
static int tank2mnum[] = {8, 0};
static Method tank2methods[] = {13, calcpointsV, NULL,
0, NULL, NULL};
static StaticDC tankstaticdcs[] = {
tank0, tank0pnum, tank0mnum, tank0methods, COLOR_TANK,
tank1, tank1pnum, tank1mnum, tank1methods, COLOR_TANK,
tank2, tank2pnum, tank2mnum, tank2methods, COLOR_TANK};
static float* tankvars[] = {vars0, vars0, vars1};
static float tankyoffsets[] = {0.0, 5.0, 32.0};
static float tankzoffsets[] = {-25.0, 0.0, 0.0};
static Coord3d super0[] = {
15, 60, -15, 30, -60, -15, 30, -60, 19, 15, 60, -15,
-15, 60, -15, -30, -60, -15, -30, -60, 19, -15, 60, -15,
-30, -60, 19, 30, -60, 19, -30, -60, -15, 30, -60, -15};
static int super0pnum[] = {8, 0};
static int super0mnum[] = {4, 0};
static Method super0methods[] = {12, calcpointsV, NULL,
0, NULL, NULL};
static Coord3d super1[] = {
0, 47, -18, 13, -48, 9, 11, -48, 19, 11, -13, 19,
0, 47, -18, -13, -48, 9, -11, -48, 19, -11, -13, 19,
0, 47, -18, 11, -48, 19, -11, -48, 19, 11, -13, 19,
-11, -13, 19};
static int super1pnum[] = {9, 0};
static int super1mnum[] = {4, 0};
static Method super1methods[] = {13, calcpointsV, NULL,
0, NULL, NULL};
static Coord3d super2[] = {
3, -36, 0, 3, 36, 0, -3, -36, 0, -3, 36, 0,
3, -27, -6, 3, 36, -6, -3, -27, -6, -3, 36, -6,
3, 36, -6, 3, 36, 0, -3, 36, 0, -3, 36, -6,
3, 36, -6};
static int super2pnum[] = {4, 0};
static int super2mnum[] = {5, 0};
static Method super2methods[] = {9, calcpointsV, NULL,
0, NULL, NULL};
static StaticDC superstaticdcs[] = {
super0, super0pnum, super0mnum, super0methods, COLOR_SUPER,
super1, super1pnum, super1mnum, super1methods, COLOR_SUPER,
super2, super2pnum, super2mnum, super2methods, COLOR_SUPER};
static float superyoffsets[] = {0.0, -12.0, 19.0};
static float superzoffsets[] = {-25.0, -15.0, 0.0};
static Coord3d missile0[] = {
15, -30, -25, 25, -30, 0, 0, -45, 0, 15, -30, -25,
-15, -30, -25, 0, -45, 0, 15, -30, 25, -15, -30, 25,
0, -45, 0, -25, -30, 0, -15, -30, 25};
static int missile0pnum[] = {11, 0};
static int missile0mnum[] = {0};
static Method missile0methods[] = {11, calcpointsV, NULL,
0, NULL, NULL};
static Coord3d missile1[] = {
15, -30, -25, 0, 50, 0, 25, -30, 0, 15, -30, 25,
0, 50, 0, -15, -30, -25, -25, -30, 0, 0, 50, 0,
-15, -30, 25};
static int missile1pnum[] = {9, 0};
static int missile1mnum[] = {0};
static Method missile1methods[] = {9, calcpointsV, NULL,
0, NULL, NULL};
static Coord3d missile2[] = {
13, -17, 11, 15, -30, 5, 23, -38, -10, 23, 0, -10,
13, -17, 11};
static int missile2pnum[] = {5, 0};
static int missile2mnum[] = {0};
static Method missile2methods[] = {5, calcpointsV, NULL,
0, NULL, NULL};
static Coord3d missile3[] = {
-13, -17, 11, -15, -30, 5, -23, -38, -10, -23, 0, -10,
-13, -17, 11};
static int missile3pnum[] = {5, 0};
static int missile3mnum[] = {0};
static Method missile3methods[] = {5, calcpointsV, NULL,
0, NULL, NULL};
static StaticDC missilestaticdcs[] = {
missile0, missile0pnum, missile0mnum, missile0methods, COLOR_MISSILE,
missile1, missile1pnum, missile1mnum, missile1methods, COLOR_MISSILE,
missile2, missile2pnum, missile2mnum, missile2methods, COLOR_MISSILE,
missile3, missile3pnum, missile3mnum, missile3methods, COLOR_MISSILE};
static float* missilevars[] = {vars0, vars0, vars1, vars1};
static float missileyoffsets[] = {0.0, 0.0, 0.0, 0.0};
static float missilezoffsets[] = {0.0, 0.0, -30.0, -30.0};
static Coord3d copter0[] = {
6, 100, 0, 6, 100, 0, -6, -100, 0, 6, -100, 0,
-6, 100, 0, 6, 100, 0};
static int copter0pnum[] = {6, 0};
static int copter0mnum[] = {0};
static Method copter0methods[] = {6, calcpointsVI, NULL,
0, NULL, NULL};
static Coord3d copter1[] = {
0, -32, -10, 7, 52, -34, 10, 48, -14, 0, -34, 0,
0, -52, 28, 0, -62, 28, 0, -48, -10, 0, -32, -10,
-7, 52, -34, -10, 48, -14, 0, -34, 0};
static int copter1pnum[] = {11, 0};
static int copter1mnum[] = {0};
static Method copter1methods[] = {11, calcpointsV, NULL,
0, NULL, NULL};
static Coord3d copter2[] = {
-14, 34, -34, 14, 34, -34, 0, 60, -14, -14, 34, -34,
-7, -30, -34, 7, -30, -34, 14, 34, -34, 26, 34, -14,
0, 60, -14, -26, 34, -14, -10, -34, -14, 10, -34, -14,
26, 34, -14, 4, 20, 16, 0, 22, 16, -4, 20, 16,
-4, -22, 16, 4, -22, 16, 4, 20, 16, -10, -34, -14,
-4, -22, 16, 10, -34, -14, 4, -22, 16, 0, 22, 16,
0, 60, -14, -14, 34, -34, -26, 34, -14, -26, 34, -14,
-4, 20, 16};
static int copter2pnum[] = {19, 0};
static int copter2mnum[] = {10, 0};
static Method copter2methods[] = {29, calcpointsV, NULL,
0, NULL, NULL};
static StaticDC copterstaticdcs[] = {
copter0, copter0pnum, copter0mnum, copter0methods, COLOR_COPTER,
copter1, copter1pnum, copter1mnum, copter1methods, COLOR_COPTER,
copter2, copter2pnum, copter2mnum, copter2methods, COLOR_COPTER};
static float* coptervars[] = {vars2, vars0, vars1};
static float copteryoffsets[] = {0.0, -82.0, 0.0};
static float copterzoffsets[] = {30.0, 0.0, 0.0};
static StaticDCp staticdcs[] = {
NULL, NULL, tankstaticdcs, superstaticdcs,
missilestaticdcs, copterstaticdcs};
static float* yoffsets[] = {
NULL, NULL, tankyoffsets, superyoffsets,
missileyoffsets, copteryoffsets};
static float* zoffsets[] = {
NULL, NULL, tankzoffsets, superzoffsets,
missilezoffsets, copterzoffsets};
static float* *vars[] = {
NULL, NULL, tankvars, tankvars,
missilevars, coptervars};
static int pieces[] = {0, 0, 3, 3, 4, 3};
static float gravity = 1.0;
int color, i, j, p;
DCp dc;
Methodp methods;
float yoffset, dx, dy, temp;
static int threshold = 0.8;
Float2d pro;
float* v;
if (g->type == IS_LANDER) {
if (g->attr & EXERASE || g->ecount >= 40) {
g->dc[0].seen = False;
drawobject(g, pl);
g->attr = 0;
return;
} /* lander just blinks on every */
if (g->dc[0].seen && g->ccount%3) /* 3rd cycle */
g->dc[0].seen = False;
else
g->ccount = 0;
drawobject(g, pl);
g->ccount++;
return;
}
p = pieces[g->lntype];
gprsetdrawvalue(opt->cpi[COLOR_BG]);
for (i=0; i<p; i++) {
dc = &g->dc[i];
if (dc->last)
displayobject(dc);
}
if (g->attr & EXERASE || g->ecount >= 40) {
g->attr = 0;
return;
}
if (!(g->attr & HAS_DC)) {
g->attr |= HAS_DC;
for (i=0; i<p; i++) {
dc = &g->dc[i];
dc->s = staticdcs[g->lntype]+i;
switch (g->type) {
case IS_CUBE:
case IS_PYRAMID:
case IS_LANDER:
case IS_MISSILE:
case IS_COPTER:
case IS_SUPER:
case IS_TANK:
dc->fades = opt->fading_colors - 1;
dc->basecolor = dc->s->basecolor;
break;
case IS_SALVO:
dc->fades = False;
if (g->salvo == pl)
dc->basecolor = COLOR_PSALVO;
else
dc->basecolor = COLOR_ESALVO;
break;
}
dc->cta = g->ca;
dc->sta = g->sa;
dc->ctp = 1.0;
dc->stp = 0.0;
yoffset = *(yoffsets[g->lntype]+i);
dc->pos.x = -yoffset * g->sa;
dc->pos.y = yoffset * g->sa;
dc->pos.z = g->z + *(zoffsets[g->lntype]+i);
dc->vel.x = frand() * 20.0 - 10.0;
dc->vel.y = frand() * 20.0 - 10.0;
dc->vel.z = 12.5 + frand() * 7.5;
}
if (g->type == IS_COPTER)
g->dc[0].vel.z += 6.0;
}
for (i=0; i<p; i++) {
dc = &g->dc[i];
dx = g->x + dc->pos.x - pl->x;
dy = g->y + dc->pos.y - pl->y;
if (sqrt(dx*dx + dy*dy) < 2000.0) {
if (dc->fades) {
color = g->range/OUT_OF_DRAWING_RANGE * opt->fading_colors;
if (color >= opt->fading_colors)
color = opt->fading_colors-1;
}
else
color = 0;
gprsetdrawvalue(color + opt->cpi[dc->basecolor]);
pro.x = dx * pl->ca + dy * pl->sa;
pro.y = -dx * pl->sa + dy * pl->ca;
if (pro.y/fabs(pro.x+1) > threshold) {
methods = dc->s->methods;
for (j=0; methods->num; methods++) {
methods->calc(dc, methods, j, g, pl);
j += methods->num;
}
displayobject(dc);
dc->last = True;
}
else
dc->last = False;
}
else
dc->last = False;
dc->pos.x += dc->vel.x;
dc->pos.y += dc->vel.y;
dc->vel.z -= gravity;
dc->pos.z += dc->vel.z;
if (dc->pos.z < -40.0) {
dc->pos.z = -40.0;
dc->vel.z *= -0.2;
}
v = vars[g->lntype][i];
temp = dc->cta;
dc->cta = dc->cta*v[0] - dc->sta*v[1];
dc->sta = dc->sta*v[0] + temp*v[1];
temp = dc->ctp;
dc->ctp = dc->ctp*v[2] - dc->stp*v[3];
dc->stp = dc->stp*v[2] + temp*v[3];
}
}
void explodesalvo (g, pl)
Genericp g;
Genericp pl;
{
float mrx[5], mry[5];
float mrz[5], xmoff[5], ymoff[5], zmoff[5];
static float gravity = 1.0;
int i, j;
Coord2dp point, first;
if (g->dc[0].last) {
gprsetdrawvalue(opt->cpi[COLOR_BG]);
multiline(g->dc[0].points, 5);
}
if (g->attr & EXERASE || g->ecount >= 20) {
g->attr = 0;
return;
}
if (g->attr & IS_NEW) {
g->ccount = 0;
g->attr &= ~IS_NEW;
for (j=0; j<5; j++) {
g->dc[j].vel.x = frand() * 20.0 - 10.0;
g->dc[j].vel.y = frand() * 20.0 - 10.0;
g->dc[j].vel.z = -7.5 - frand() * 5.0;
g->dc[j].pos.x = 0.0;
g->dc[j].pos.y = 0.0;
g->dc[j].pos.z = 0.0;
}
}
if (g->dc[0].seen) {
if (g->salvo == pl)
gprsetdrawvalue(opt->cpi[COLOR_PSALVO]);
else
gprsetdrawvalue(opt->cpi[COLOR_ESALVO]);
for (i=0; i<5; i++) {
g->dc[i].pos.x += g->dc[i].vel.x;
g->dc[i].pos.y += g->dc[i].vel.y;
g->dc[i].vel.z += gravity;
g->dc[i].pos.z -= g->dc[i].vel.z;
}
point = g->dc[0].points;
for (i=0; i<5; i++) {
xmoff[i] = g->dc[i].pos.x + g->x - pl->x;
ymoff[i] = g->dc[i].pos.y + g->y - pl->y;
zmoff[i] = g->dc[i].pos.z;
mrx[i] = xmoff[i] * pl->ca + ymoff[i] * pl->sa;
mry[i] = -xmoff[i] * pl->sa + ymoff[i] * pl->ca;
mrz[i] = zmoff[i];
if (mry[i] < 10.0)
mry[i] = 10.0;
first = point++;
point->x = first->x = 500 + mrx[i] / mry[i] * 450;
first->y = 260 - mrz[i] / mry[i] * 450;
point->y = first->y+2;
point++;
}
multiline(g->dc[0].points, 5);
g->dc[0].last = True;
}
else
g->dc[0].last = False;
g->ccount++;
}